package com.fudan.adse.component;

import com.fudan.adse.domain.bo.*;
import com.fudan.adse.domain.cont.SeatStatus;
import com.fudan.adse.grpc.*;
import com.fudan.adse.utils.DateTimeUtil;
import com.google.protobuf.Empty;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 处理服务间调用返回结果
 *
 * @author Jerry Zhang
 * create: 2022-11-19 20:02
 */
@Component
public class GrpcServiceStub {
    @GrpcClient("ticket-cinema")
    CinemaGrpc.CinemaBlockingStub cinemaBlockingStub;
    @GrpcClient("ticket-film")
    FilmGrpc.FilmBlockingStub filmBlockingStub;
    @GrpcClient("ticket-auth")
    AuthGrpc.AuthBlockingStub authBlockingStub;
    @GrpcClient("ticket-user")
    UserGrpc.UserBlockingStub userBlockingStub;
    @GrpcClient("ticket-order")
    OrderGrpc.OrderBlockingStub orderBlockingStub;

    //----------- 用户管理服务 -----------

    /**
     * 根据用户名获取用户信息、角色信息
     *
     * @param username
     * @return
     */
    public UserBO loadUserByUsername(String username) {
        UserResponse response = userBlockingStub.loadUserByUsername(UserQuery.newBuilder()
                .setUsername(username).build());
        if (response != null) {
            UserBO userBO = UserBO.builder()
                    .uuid(response.getUuid())
                    .username(username)
                    .password(response.getPassword())
                    .status(response.getStatus())
                    .build();
            userBO.setRoles(response.getRolesList());
            return userBO;
        }
        return null;
    }

    //----------- 订单管理服务 -----------

    /**
     * 获取某场次位置 最新 使用情况
     *
     * @param rowPieceId
     * @return
     */
    public List<SeatBO> listSeatsByRowPieceId(Integer rowPieceId) {
        OrderResponse response = orderBlockingStub.listSeatsByRowPieceId(OrderQuery.newBuilder()
                .addRowPieceId(rowPieceId).build());
        List<SeatBO> seats = new ArrayList<>();
        if (response != null && response.getSeatCount() > 0) {
            for (int i = 0; i < response.getSeatCount(); i++) {
                seats.add(SeatBO.builder()
                        .id(response.getSeat(i).getId())
                        .row(response.getSeat(i).getRow())
                        .col(response.getSeat(i).getCol())
                        .status(SeatStatus.valueOf(response.getSeat(i).getStatus()))
                        .rowPieceId(rowPieceId)
                        .build());
            }
        }
        return seats;
    }

    /**
     * 影片开始放映后，将相关影票设置为已使用
     *
     * @param rowPieceIds
     */
    public void checkAllTickets(List<Integer> rowPieceIds) {
        orderBlockingStub.checkAllTickets(OrderQuery.newBuilder()
                .addAllRowPieceId(rowPieceIds).build());
    }

    //----------- 影片管理服务 -----------

    /**
     * 获取某影院的场次数据、某影片的场次数据
     *
     * @return
     */
    public List<Integer> listRowPiecesByCinemaOrFilm(Integer cinemaId, Integer filmId, String since, String until) {
        ListResponse response = filmBlockingStub.listRowPiecesByCinemaOrFilm(RowPieceQuery.newBuilder()
                .setCinemaId(cinemaId)
                .setFilmId(filmId)
                .setSince(since)
                .setUntil(until)
                .build());
        return response.getIdList();
    }

    /**
     * 获取某排片场次详细数据
     *
     * @param rowPieceId
     * @return
     */
    public RowPieceBO getRowPieceById(Integer rowPieceId) {
        RowPieceResponse response = filmBlockingStub.getRowPieceById(RowPieceQuery.newBuilder()
                .setRowPieceId(rowPieceId).build());
        if (response != null) {
            return RowPieceBO.builder()
                    .id(rowPieceId)
                    .cinemaId(response.getCinemaId())
                    .filmId(response.getFilmId())
                    .roomId(response.getRoomId())
                    .startTime(DateTimeUtil.stringToDate(response.getStartTime()))
                    .endTime(DateTimeUtil.stringToDate(response.getEndTime()))
                    .price(response.getPrice())
                    .remainCapacity(response.getRemainCapacity())
                    .build();
        }
        return null;
    }

    /**
     * 更新影票余量
     * @param rowPieceId
     * @param count
     * @param seats
     */
    public void updateRemainingCapacity(Integer rowPieceId, Integer count, String seats) {
        filmBlockingStub.updateRemainCapacity(SoldSeatsQuery.newBuilder()
                .setRowPieceId(rowPieceId)
                .setCount(count)
                .setSeats(seats)
                .build());
    }

    //----------- 影院管理服务 -----------

    /**
     * 根据影院 id 获取详细数据
     *
     * @param cinemaId
     * @return
     */
    public CinemaBO getCinemaById(Integer cinemaId) {
        CinemaQuery query = CinemaQuery.newBuilder().addAllId(List.of(cinemaId)).build();
        CinemaResponse response = cinemaBlockingStub.listCinemasByCondition(query);
        if (response != null && !response.getCinemaList().isEmpty()) {
            // todo 获取 location
            return CinemaBO.builder()
                    .id(response.getCinema(0).getId())
                    .name(response.getCinema(0).getName())
                    .locationDetail(response.getCinema(0).getLocationDetail())
                    .status(response.getCinema(0).getStatus())
                    .build();
        }
        return null;
    }

    /**
     * 根据影院 id 获取详细数据
     *
     * @param cinemaIds
     * @return
     */
    public List<CinemaBO> listCinemasByIds(List<Integer> cinemaIds) {
        CinemaQuery query = CinemaQuery.newBuilder().addAllId(cinemaIds).build();
        CinemaResponse response = cinemaBlockingStub.listCinemasByCondition(query);
        List<CinemaBO> ret = new ArrayList<>();
        if (response != null && !response.getCinemaList().isEmpty()) {
            for (int i = 0; i < response.getCinemaCount(); i++) {
                ret.add(CinemaBO.builder()
                        .id(response.getCinema(i).getId())
                        .name(response.getCinema(i).getName())
                        .locationDetail(response.getCinema(i).getLocationDetail())
                        .status(response.getCinema(i).getStatus())
                        .build());
            }
        }
        return ret;
    }

    /**
     * 根据影院 id 获取影厅详细数据
     *
     * @param cinemaId
     * @return
     */
    public List<RoomBO> listRoomsByCinemaId(Integer cinemaId) {
        RoomResponse response = cinemaBlockingStub.listRoomsByCinemaId(CinemaQuery.newBuilder()
                .addId(cinemaId).build());
        List<RoomBO> rooms = new ArrayList<>();
        if (response != null && response.getRoomCount() > 0) {
            for (int i = 0; i < response.getRoomCount(); i++) {
                rooms.add(RoomBO.builder()
                        .id(response.getRoom(i).getId())
                        .cinemaId(response.getRoom(i).getCinemaId())
                        .name(response.getRoom(i).getName())
                        .capacity(response.getRoom(i).getCapacity())
                        .description(response.getRoom(i).getDescription())
                        .status(response.getRoom(i).getStatus())
                        .build());
            }
        }
        return rooms;
    }
}
